package mbp.gui.panels;

import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.JTextField;
import javax.swing.JLabel;
import javax.swing.table.DefaultTableModel;

import org.apache.log4j.Logger;

import mbp.base.FeatureType;
import mbp.base.GuiFunction;
import mbp.base.Record;
import mbp.base.ResourceSet;
import mbp.base.ServiceStage;
import mbp.core.CounterOffer;
import mbp.core.Resource;
import mbp.core.ResourceTypeBuilder;
import mbp.exceptions.InvalidFeatureNameException;
import mbp.exceptions.InvalidFeatureTypeException;
import mbp.exceptions.InvalidFeatureValueException;
import mbp.gui.base.ResourceListScrollPane;
import mbp.gui.frames.ResourceEditor;
import mbp.gui.frames.TermEditor;
import mbp.message.ObjectBuilder;
import mbp.message.resource;

import javax.swing.JSeparator;
import javax.swing.JButton;
import java.awt.Font;

/**
 * Panel edycji i testowania obiektu kontroferta
 * @author wojtekw
 *
 */
public class COfferDetailsPanel extends JPanel implements ActionListener
{
	private JTextField txtMaxTerm;
	private JTable table;
	private DefaultTableModel modelInt;
	private ResourceListScrollPane listAdvance;
	private ResourceListScrollPane listStuff;
	private ResourceListScrollPane listPay;
	private CounterOffer counterOffer;
	private JButton btnSave;
	ObjectBuilder objectBuilder;
	
	private Logger logger = Logger.getLogger(this.getClass());
	private JTextField txtUUID;
	private JTextField txtType;
	private JTextField txtServer;
	private JTextField txtClient;
	private JTextField txtAgent;

	/**
	 * Create the panel.
	 */
	public COfferDetailsPanel() 
	{
		setLayout(null);
		
		objectBuilder = new ObjectBuilder();
		
		JScrollPane scrollPane = new JScrollPane();
		scrollPane.setBounds(10, 188, 370, 61);
		add(scrollPane);
		
		txtMaxTerm = new JTextField();
		txtMaxTerm.setColumns(10);
		txtMaxTerm.setBounds(10, 168, 86, 20);
		add(txtMaxTerm);
		
		JLabel label = new JLabel("Max realize term");
		label.setFont(new Font("Dialog", Font.PLAIN, 12));
		label.setBounds(99, 171, 125, 14);
		add(label);
		
		modelInt = new DefaultTableModel();
		modelInt.addColumn("Resource");
		modelInt.addColumn("Condition");
		table = new JTable(modelInt);
		table.setFillsViewportHeight(true);
		scrollPane.setViewportView(table);
		
		listAdvance = new ResourceListScrollPane(){
			public void processDoubleClick(){
				//System.out.println(counterOffer.getServiceType().GetServiceTypeName());
				//System.out.println(getSelectedRow());
				int index = getSelectedRow();
				
				if(index!=-1)
				{
//					if(counterOffer.getResourceSetIn(0).get(index).getResouceInfo() != null)
//					{
//						//ObjectBuilder objectBuilder = new ObjectBuilder();
//						Resource rc = counterOffer.getResourceSetIn(0).get(index).getResouceInfo();
//						ResourceEditor resourceEditor = new ResourceEditor(rc, GuiFunction.EDITOR, null);
//						resourceEditor.setVisible(true);
//					}
					
					if(counterOffer.getResourcesIn(ServiceStage.ADVANCE).get(index).value0 != null)
					{
						Resource rc = counterOffer.getResourcesIn(ServiceStage.ADVANCE).get(index).value0;
						//Resource rc = objectBuilder.getResource(rci);
						ResourceEditor resourceEditor = new ResourceEditor(rc, GuiFunction.EDITOR, null);
						resourceEditor.setVisible(true);
					}
				}
			}
			
			public void addResource(){
				int index = getSelectedRow();
				String type = (String) getTableModel().getValueAt(index, 1);
				ResourceTypeBuilder rtb = new ResourceTypeBuilder("");
				Resource rc = new Resource(rtb.GetResourceType(type), "0");
				setDefaultValues(rc);
								
				//counterOffer.getResourceSetIn(0).get(index).setResouceInfo(rc);
				counterOffer.getResourcesIn(ServiceStage.ADVANCE).get(index).value0 = rc;
				
				getTableModel().setValueAt("SET", index, 3);
				
				ResourceEditor resourceEditor = new ResourceEditor(rc, GuiFunction.EDITOR, null);
				resourceEditor.setVisible(true);
				
			}
			
			public void removeResource() {
				int index = getSelectedRow();
				//counterOffer.getResourceSetIn(0).get(index).setResouceInfo(null);
				counterOffer.getResourcesIn(ServiceStage.ADVANCE).get(index).value0 = null;
				getTableModel().setValueAt("", index, 3);
			}
		};
		listAdvance.setBounds(10, 303, 200, 80);
		add(listAdvance);
		
		/**
		 * Utworzenie obiektu ResourceListScrollPane i zaprogramowanie metod: popupmenu oraz double click
		 */
		listStuff = new ResourceListScrollPane(){
			public void processDoubleClick(){
				//System.out.println(counterOffer.getServiceType().GetServiceTypeName());
				//System.out.println(getSelectedRow());
				int index = getSelectedRow();
				
				if(index!=-1)
				{
//					if(counterOffer.getResourceSetIn(1).get(index).getResouceInfo() != null)
//					{
//						//ObjectBuilder objectBuilder = new ObjectBuilder();
//						Resource rc = counterOffer.getResourceSetIn(1).get(index).getResouceInfo();
//						ResourceEditor resourceEditor = new ResourceEditor(rc, GuiFunction.EDITOR, null);
//						resourceEditor.setVisible(true);
//					}
					
					if(counterOffer.getResourcesIn(ServiceStage.STUFF).get(index).value0 != null)
					{
						Resource rc = counterOffer.getResourcesIn(ServiceStage.STUFF).get(index).value0;
						//Resource rc = objectBuilder.getResource(rci);
						ResourceEditor resourceEditor = new ResourceEditor(rc, GuiFunction.EDITOR, null);
						resourceEditor.setVisible(true);
					}
				}
			}
			
			public void addResource(){
				int index = getSelectedRow();
				String type = (String) getTableModel().getValueAt(index, 1);
				ResourceTypeBuilder rtb = new ResourceTypeBuilder("");
				Resource rc = new Resource(rtb.GetResourceType(type), "0");
				setDefaultValues(rc);
								
				//counterOffer.getResourceSetIn(1).get(index).setResouceInfo(rc);
				counterOffer.getResourcesIn(ServiceStage.STUFF).get(index).value0 = rc;
				
				getTableModel().setValueAt("SET", index, 3);
				
				ResourceEditor resourceEditor = new ResourceEditor(rc, GuiFunction.EDITOR, null);
				resourceEditor.setVisible(true);
				
			}
			
			public void removeResource() {
				int index = getSelectedRow();
				//counterOffer.getResourceSetIn(1).get(index).setResouceInfo(null);
				counterOffer.getResourcesIn(ServiceStage.STUFF).get(index).value0 = null;
				getTableModel().setValueAt("", index, 3);
			}
			
			public void changeTerm()
			{
				int index = getSelectedRow();
				//TermEditor te = new TermEditor(counterOffer.getResourceSetIn(1).get(index), getTableModel(), index);
				TermEditor te = new TermEditor(counterOffer.getResourcesIn(ServiceStage.STUFF).get(index), getTableModel(), index);
				te.setVisible(true);
			}
			
			
		};		
		listStuff.setBounds(220, 303, 200, 80);
		add(listStuff);
		
		listPay = new ResourceListScrollPane(){
			public void processDoubleClick(){
				//System.out.println(counterOffer.getServiceType().GetServiceTypeName());
				//System.out.println(getSelectedRow());
				int index = getSelectedRow();
				
				if(index!=-1)
				{
//					if(counterOffer.getResourceSetIn(2).get(index).getResouceInfo() != null)
//					{
//						//ObjectBuilder objectBuilder = new ObjectBuilder();
//						Resource rc = counterOffer.getResourceSetIn(2).get(index).getResouceInfo();
//						ResourceEditor resourceEditor = new ResourceEditor(rc, GuiFunction.EDITOR, null);
//						resourceEditor.setVisible(true);
//					}
					
					if(counterOffer.getResourcesIn(ServiceStage.PAY).get(index).value0 != null)
					{
						Resource rc = counterOffer.getResourcesIn(ServiceStage.PAY).get(index).value0;
						//Resource rc = objectBuilder.getResource(rci);
						ResourceEditor resourceEditor = new ResourceEditor(rc, GuiFunction.EDITOR, null);
						resourceEditor.setVisible(true);
					}
				}
			}
			
			public void addResource(){
				int index = getSelectedRow();
				String type = (String) getTableModel().getValueAt(index, 1);
				ResourceTypeBuilder rtb = new ResourceTypeBuilder("");
				Resource rc = new Resource(rtb.GetResourceType(type), "0");
				setDefaultValues(rc);
								
				//counterOffer.getResourceSetIn(2).get(index).setResouceInfo(rc);
				counterOffer.getResourcesIn(ServiceStage.PAY).get(index).value0 = rc;
				
				getTableModel().setValueAt("SET", index, 3);
				
				ResourceEditor resourceEditor = new ResourceEditor(rc, GuiFunction.EDITOR, null);
				resourceEditor.setVisible(true);
				
			}
			
			public void removeResource() {
				int index = getSelectedRow();
				//counterOffer.getResourceSetIn(2).get(index).setResouceInfo(null);
				counterOffer.getResourcesIn(ServiceStage.PAY).get(index).value0 = null;
				getTableModel().setValueAt("", index, 3);
			}
		};
		listPay.setBounds(430, 303, 200, 80);
		add(listPay);
		
		JLabel lblAdvance = new JLabel("Advance");
		lblAdvance.setBounds(10, 288, 100, 14);
		add(lblAdvance);
		
		JLabel lblStuff = new JLabel("Stuff");
		lblStuff.setBounds(220, 288, 80, 14);
		add(lblStuff);
		
		JLabel lblPay = new JLabel("Pay");
		lblPay.setBounds(430, 288, 46, 14);
		add(lblPay);
		
		JSeparator separator = new JSeparator();
		separator.setBounds(10, 275, 620, 2);
		add(separator);
		
		JLabel lblResourcesIn = new JLabel("Resources in");
		lblResourcesIn.setFont(new Font("Dialog", Font.PLAIN, 12));
		lblResourcesIn.setBounds(10, 260, 100, 14);
		add(lblResourcesIn);
		
		JSeparator separator_1 = new JSeparator();
		separator_1.setBounds(10, 155, 620, 2);
		add(separator_1);
		
		JLabel lblResourcesOut = new JLabel("Resources out");
		lblResourcesOut.setFont(new Font("Dialog", Font.PLAIN, 12));
		lblResourcesOut.setBounds(10, 140, 100, 14);
		add(lblResourcesOut);
		
		btnSave = new JButton("Save");
		btnSave.setBounds(541, 225, 89, 23);
		add(btnSave);
		btnSave.addActionListener(this);
		
		JSeparator separator_2 = new JSeparator();
		separator_2.setBounds(10, 34, 620, 2);
		add(separator_2);
		
		JLabel lblNewLabel = new JLabel("Details");
		lblNewLabel.setFont(new Font("Dialog", Font.PLAIN, 12));
		lblNewLabel.setBounds(10, 19, 46, 14);
		add(lblNewLabel);
		
		JLabel label_1 = new JLabel("UUID");
		label_1.setBounds(10, 47, 70, 14);
		add(label_1);
		
		txtUUID = new JTextField();
		txtUUID.setEditable(false);
		txtUUID.setColumns(10);
		txtUUID.setBounds(10, 61, 310, 20);
		add(txtUUID);
		
		JLabel label_2 = new JLabel("Type");
		label_2.setBounds(330, 47, 46, 14);
		add(label_2);
		
		txtType = new JTextField();
		txtType.setEditable(false);
		txtType.setColumns(10);
		txtType.setBounds(330, 61, 150, 20);
		add(txtType);
		
		JLabel lblServer = new JLabel("Server");
		lblServer.setBounds(330, 92, 46, 14);
		add(lblServer);
		
		txtServer = new JTextField();
		txtServer.setEditable(false);
		txtServer.setColumns(10);
		txtServer.setBounds(330, 106, 150, 20);
		add(txtServer);
		
		JLabel label_4 = new JLabel("Client");
		label_4.setBounds(10, 92, 46, 14);
		add(label_4);
		
		txtClient = new JTextField();
		txtClient.setEditable(false);
		txtClient.setColumns(10);
		txtClient.setBounds(10, 106, 150, 20);
		add(txtClient);
		
		JLabel lblAgent = new JLabel("Agent");
		lblAgent.setBounds(170, 92, 46, 14);
		add(lblAgent);
		
		txtAgent = new JTextField();
		txtAgent.setEditable(false);
		txtAgent.setColumns(10);
		txtAgent.setBounds(170, 106, 150, 20);
		add(txtAgent);

	}
	
	public void loadCOffer(CounterOffer counterOffer)
	{
		this.counterOffer = counterOffer;
		int rowsCount = 0;
		
		txtUUID.setText(counterOffer.GetUUID());
		txtType.setText(counterOffer.getServiceType().getServiceTypeName());
		txtServer.setText(counterOffer.getServerName());
		txtAgent.setText(counterOffer.getAgentName());
		txtClient.setText(counterOffer.getClientName());
		
		txtMaxTerm.setText(counterOffer.getRealizeMaxTU().toString());
		
		/**
		 * Wyczyszczenie tabeli
		 */
		for( int i = modelInt.getRowCount() - 1; i >= 0; i-- )
		{
		    modelInt.removeRow(i);
		}
		
		for(int i = 0; i<counterOffer.getResourcesOut().size(); i++)
		{
			String type = counterOffer.getResourcesOut().get(i).getType().getResourceTypeName();
			String cnd = counterOffer.getResourcesOut().get(i).getCondition();
			
			modelInt.insertRow(rowsCount, new Object[]{type,  cnd});
			rowsCount++;
		}
		
		List<Record<Resource, Object[]>> rcInAdvanceSet = counterOffer.getResourcesIn(ServiceStage.ADVANCE);
		List<Record<Resource, Object[]>> rcInStuffSet = counterOffer.getResourcesIn(ServiceStage.STUFF);
		List<Record<Resource, Object[]>> rcInPaySet = counterOffer.getResourcesIn(ServiceStage.PAY);
		
		for(int i = 0; i<rcInAdvanceSet.size(); i++)
		{
			
			listAdvance.getTableModel().insertRow(i, new Object[]{i, 
					rcInAdvanceSet.get(i).value1[0],
					"-",
					rcInAdvanceSet.get(i).value0});
		}
		
		for(int i = 0; i<rcInStuffSet.size(); i++)
		{
			listStuff.getTableModel().insertRow(i, new Object[]{i, 
					rcInStuffSet.get(i).value1[0], 
					rcInStuffSet.get(i).value1[1].toString(),
					rcInStuffSet.get(i).value0});
		}
		
		for(int i = 0; i<rcInPaySet.size(); i++)
		{
			listPay.getTableModel().insertRow(i, new Object[]{i, 
					rcInPaySet.get(i).value1[0], 
					"-",
					rcInPaySet.get(i).value0});
		}
		
	}
	
	/**
	 * Ustawia domyslne wartosci w polach edycyjnych dla nowo utworzonego zasobu.
	 * @param res
	 */
	public void setDefaultValues(Resource res)
	{
		Iterator it = res.getType().getFeaturesCollection().keySet().iterator();
		while (it.hasNext()) 
		{
			String key = (String)it.next();
			try 
			{
				FeatureType type = res.getFeatureType(key);
				switch(type)
				{
				case INT:
					res.setFeatureValue(key, 0);										
					break;
				case FLOAT:
					res.setFeatureValue(key, Float.parseFloat("0.0"));
					break;
				case ENUM:
					res.setFeatureValue(key, 0);
				default:				
					break;
				}
				
				res.setOwner("WojtekW");
			} 
			catch (InvalidFeatureNameException e) 
			{
				logger.error("InvalidFeatureNameException", e);
			} 
			catch (InvalidFeatureTypeException e) 
			{
				logger.error("InvalidFeatureTypeException", e);
			} 
			catch (InvalidFeatureValueException e) 
			{
				logger.error("InvalidFeatureValueException", e);
			}
			catch (Exception e)
			{
				logger.error("Exception", e);					
			}
			
		}

	}
	
	/**
	 * Zapisanie danych intencji w obiekcie kontroferta
	 */
	public void saveInResources()
	{
		for( int i = 0; i<modelInt.getRowCount(); i++ )
		{
			String cnd = (String) modelInt.getValueAt(i, 1);
			counterOffer.getResourcesOut().get(i).setCondition(cnd);
		}
		
		Integer maxterm = Integer.parseInt(txtMaxTerm.getText());
		counterOffer.setRealizeMaxTU(maxterm);
	}

	@Override
	public void actionPerformed(ActionEvent e) {
		if(e.getSource() == btnSave)
		{
			saveInResources();
		}
		
	}
}
